package com.txzt.gaea.flow.service.impl;

import com.txzt.base.core.RtnInfo;
import com.txzt.gaea.STaward.model.STAward;
import com.txzt.gaea.STaward.service.STAwardService;
import com.txzt.gaea.api.client.AdminRemoteService;
import com.txzt.gaea.api.client.AdminUserRemoteService;
import com.txzt.gaea.business.fund.domain.model.FundApply;
import com.txzt.gaea.business.fund.domain.model.FundBudget;
import com.txzt.gaea.business.fund.service.IFundApplyService;
import com.txzt.gaea.business.fund.service.IFundBudgetService;
import com.txzt.gaea.business.ident.domain.model.IdentInfo;
import com.txzt.gaea.business.ident.service.IIdentInfoService;
import com.txzt.gaea.business.plan.domain.model.PlanInfo;
import com.txzt.gaea.business.plan.service.IPlanInfoService;
import com.txzt.gaea.business.project.domain.model.ProjectFund;
import com.txzt.gaea.business.project.domain.model.ProjectFundExpenseRequest;
import com.txzt.gaea.business.project.domain.model.ProjectInfo;
import com.txzt.gaea.business.project.domain.model.ProjectNode;
import com.txzt.gaea.business.project.service.IProjectFERService;
import com.txzt.gaea.business.project.service.IProjectFundService;
import com.txzt.gaea.business.project.service.IProjectInfoService;
import com.txzt.gaea.business.project.service.IProjectNodeService;
import com.txzt.gaea.business.util.TranslateUtil;
import com.txzt.gaea.common.annotation.EntityCommonValue;
import com.txzt.gaea.common.base.service.impl.BaseServiceImpl;
import com.txzt.gaea.common.core.base.context.AdminUserContext;
import com.txzt.gaea.common.enums.*;
import com.txzt.gaea.common.exception.CustomException;
import com.txzt.gaea.common.page.PageInfoBT;
import com.txzt.gaea.common.util.StringUtil;
import com.txzt.gaea.dto.QueryUserByRoleIdDTO;
import com.txzt.gaea.dto.UserSingleDetailQueryDTO;
import com.txzt.gaea.flow.dto.FlowDefinitionQueryDTO;
import com.txzt.gaea.flow.model.*;
import com.txzt.gaea.flow.service.FlowService;
import com.txzt.gaea.flow.service.IFlowStepLogService;
import com.txzt.gaea.flow.vo.FlowBizStepVo;
import com.txzt.gaea.flow.vo.FlowDefinitionVo;
import com.txzt.gaea.upgrade.out.domain.model.OutContract;
import com.txzt.gaea.upgrade.out.domain.model.OutCoop;
import com.txzt.gaea.upgrade.out.service.IOutContractService;
import com.txzt.gaea.upgrade.out.service.IOutCoopService;
import com.txzt.gaea.upgrade.project.domain.model.BudgetManage;
import com.txzt.gaea.upgrade.project.domain.model.ProjectMain;
import com.txzt.gaea.upgrade.project.service.IBudgetManageService;
import com.txzt.gaea.upgrade.project.service.IProjectMainService;
import com.txzt.gaea.upgrade.result.domain.model.ResultBorrow;
import com.txzt.gaea.upgrade.result.domain.model.ResultInfo;
import com.txzt.gaea.upgrade.result.service.IResultBorrowService;
import com.txzt.gaea.upgrade.result.service.IResultInfoService;
import com.txzt.gaea.vo.AdminUserVO;
import lombok.extern.log4j.Log4j2;
import org.apache.commons.lang3.BooleanUtils;
import org.apache.commons.lang3.StringUtils;
import org.beetl.sql.core.engine.PageQuery;
import org.beetl.sql.core.query.LambdaQuery;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.CollectionUtils;

import java.util.*;
import java.util.concurrent.atomic.AtomicInteger;
import java.util.stream.Collectors;

@Log4j2
@Service
public class FlowServiceImpl extends BaseServiceImpl<FlowDefinition> implements FlowService {

    @Value("${tool.code}")
    String toolCode;
    @Value("${tool.version}")
    String toolVersion;

    @Autowired
    private AdminUserRemoteService adminUserRemoteService;
    @Autowired
    private FlowService flowService;
    @Autowired
    private AdminRemoteService adminRemoteService;
    @Autowired
    private IFlowStepLogService flowStepLogService;

    @Autowired
    private IPlanInfoService planInfoService;

    @Autowired
    private IIdentInfoService iIdentInfoService;

    @Autowired
    private IProjectMainService projectMainService;

    @Autowired
    private IProjectInfoService projectInfoService;

    @Autowired
    private IProjectNodeService projectNodeService;

    @Autowired
    private IProjectFundService projectFundService;

    @Autowired
    private IFundBudgetService fundBudgetService;

    @Autowired
    private STAwardService stAwardService;

    @Autowired
    private IFundApplyService fundApplyService;

    @Autowired
    private IProjectFERService projectFERService;

    @Autowired
    private IBudgetManageService budgetManageService;

    @Autowired
    private IOutCoopService outCoopService;

    @Autowired
    private IOutContractService outContractService;

    @Autowired
    private IResultInfoService resultInfoService;

    @Autowired
    private IResultBorrowService resultBorrowService;

    @Override
    public RtnInfo<?> pageList(FlowDefinitionQueryDTO flowDefinitionQueryDTO){
        if (null == flowDefinitionQueryDTO.getStatus()){
            flowDefinitionQueryDTO.setStatus(FlowStatusEnum.USABLE.getCode());
        }
        PageQuery<FlowDefinitionVo> pageQuery = new PageQuery<>(flowDefinitionQueryDTO.getOffset(),
                flowDefinitionQueryDTO.getLimit(), flowDefinitionQueryDTO);
        PageQuery<FlowDefinitionVo> result =
                this.sqlManager.pageQuery("flowDefinition.selectPageList", FlowDefinitionVo.class, pageQuery);
        //为空直接返回
        if (CollectionUtils.isEmpty(result.getList())) {
            return RtnInfo.success(new PageInfoBT<>(result));
        }
        result.getList().forEach(item -> {
            UserSingleDetailQueryDTO userSingleDetailQueryDTO = new UserSingleDetailQueryDTO();
            userSingleDetailQueryDTO.setUserId(item.getCreateBy());
            item.setCreateName(adminUserRemoteService.singleDetailQuery(userSingleDetailQueryDTO).getData().getName());
            userSingleDetailQueryDTO.setUserId(item.getUpdateBy());
            item.setUpdateName(adminUserRemoteService.singleDetailQuery(userSingleDetailQueryDTO).getData().getName());
        });
        PageInfoBT<FlowDefinitionVo> re = new PageInfoBT<>(result);
        rebuild(re);
        return RtnInfo.success(re);
    }

    private void rebuild(PageInfoBT<FlowDefinitionVo> re){
        List<FlowDefinitionVo> list = re.getRows();
        if(CollectionUtils.isEmpty(list)){
            re.setTotal(0);
            return;
        }
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public int save(FlowDefinition flowDefinition){
        flowDefinition.setVersion(1);
        flowDefinition.setStatus(FlowStatusEnum.USABLE.getCode());
        return flowService.insertInfo(flowDefinition);
    }

    @Override
    @EntityCommonValue(operation = "CREATE")
    public int insertInfo(FlowDefinition flowDefinition){
        int num = this.sqlManager.insert(flowDefinition,true);
        if (0 < num && 0 < flowDefinition.getStepList().size()){
            flowDefinition.getStepList().forEach(item -> {
                item.setFlowId(flowDefinition.getId());
                this.sqlManager.insert(item);
            });
        }
        return num;
    }

    @Override
    @EntityCommonValue(operation = "CREATE")
    @Transactional(rollbackFor = Exception.class)
    public int update(FlowDefinition flowDefinition){
        //更新原有流程状态为 1 不使用
        flowDefinition.setStatus(FlowStatusEnum.DISABLE.getCode());
        this.sqlManager.updateTemplateById(flowDefinition);
        //新增流程
        flowDefinition.setId(null);
        flowDefinition.setStatus(FlowStatusEnum.USABLE.getCode());
        flowDefinition.setVersion(flowDefinition.getVersion() + 1);
        return flowService.insertInfo(flowDefinition);
    }

    @Override
    public boolean checkFlowNameAndFlag(FlowDefinition flowDefinition){
        LambdaQuery<FlowDefinition> query = sqlManager.lambdaQuery(FlowDefinition.class);
        long num = query.andEq(FlowDefinition::getFlowName, flowDefinition.getFlowName())
                .orEq(FlowDefinition::getFlowFlag, flowDefinition.getFlowFlag())
                .andEq(FlowDefinition::getIsDelete, IsDeleteEnum.NOTDELETE.getCode())
                .andEq(FlowDefinition::getStatus, FlowStatusEnum.USABLE.getCode())
                .count();
        return 0 >= num;
    }

    @Override
    public FlowDefinition getFlowInfo(Long id){
        LambdaQuery<FlowDefinition> query = sqlManager.lambdaQuery(FlowDefinition.class);
        FlowDefinition flowDefinition = query.andEq(FlowDefinition::getId,id).single();
        if (null != flowDefinition) {
            LambdaQuery<FlowStep> queryStep = sqlManager.lambdaQuery(FlowStep.class);
            List<FlowStep> stepList = queryStep.andEq(FlowStep::getFlowId,flowDefinition.getId()).select();
            flowDefinition.setStepList(stepList);
        }
        return flowDefinition;
    }

    /*  业务流程逻辑处理  */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public Long startFlow(Long bizId, String bizTable, String bizStatusCol,
                             Integer bizBackStatus, Integer bizPassStatus, String flowFlag){
        if (null == bizId || StringUtil.isEmpty(bizTable) || StringUtil.isEmpty(flowFlag)){
            return null;
        }
        //查询当前可用流程
        LambdaQuery<FlowDefinition> query = sqlManager.lambdaQuery(FlowDefinition.class);
        FlowDefinition currentFlowInfo = query.andEq(FlowDefinition::getFlowFlag, flowFlag)
                .andEq(FlowDefinition::getStatus, FlowStatusEnum.USABLE.getCode())
                .andEq(FlowDefinition::getIsDelete, IsDeleteEnum.NOTDELETE.getCode())
                .single();
        if (null == currentFlowInfo){
            return null;
        }
        LambdaQuery<FlowStep> queryStep = sqlManager.lambdaQuery(FlowStep.class);
        List<FlowStep> stepList = queryStep.andEq(FlowStep::getFlowId, currentFlowInfo.getId())
                .orderBy("sort asc").select();
        if (0 == stepList.size()){
            return null;
        }
        //存入业务流程表
        FlowBiz flowBiz = new FlowBiz();
        flowBiz.setFlowId(currentFlowInfo.getId());
        flowBiz.setBizId(bizId);
        flowBiz.setFlowName(currentFlowInfo.getFlowName());
        flowBiz.setFlowFlag(currentFlowInfo.getFlowFlag());
        flowBiz.setFlowVersion(currentFlowInfo.getVersion());
        flowBiz.setBizTable(bizTable);
        flowBiz.setCurrentStep(stepList.get(0).getSort());
        flowBiz.setTotalStep(stepList.size());
        flowBiz.setCurrentStepName(stepList.get(0).getStepName());
        flowBiz.setCurrentStepMember(stepList.get(0).getStepMember());
        flowBiz.setCurrentStatus(FlowBizStatusEnum.CHECK.getCode());
        flowBiz.setBizStatusCol(bizStatusCol);
        flowBiz.setBizBackStatus(bizBackStatus);
        flowBiz.setBizPassStatus(bizPassStatus);
        int fbNum = flowService.insertFlowBiz(flowBiz);
        if (0 == fbNum){
            return null;
        }
        AtomicInteger stepNum = new AtomicInteger();
        stepList.forEach(item -> {
            FlowBizStep flowBizStep = new FlowBizStep();
            flowBizStep.setFlowBizId(flowBiz.getId());
            flowBizStep.setStepNo(item.getSort());
            flowBizStep.setStepMember(item.getStepMember());
            flowBizStep.setStepName(item.getStepName());
            stepNum.addAndGet(flowService.insertFlowBizStep(flowBizStep));
        });
        if (stepList.size() != stepNum.get()){
            return null;
        }
        return flowBiz.getId();
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public boolean nextStep(Long bizFlowId, int status, String comment){
        if (null == bizFlowId){
            return false;
        }
        //获取当前流程
        LambdaQuery<FlowBiz> query = sqlManager.lambdaQuery(FlowBiz.class);
        FlowBiz currentFlowBiz = query.andEq(FlowBiz::getId,bizFlowId)
                .andEq(FlowBiz::getIsDelete,IsDeleteEnum.NOTDELETE.getCode())
                .single();
        if (null == currentFlowBiz){
            return false;
        }
        LambdaQuery<FlowBizStep> queryStep = sqlManager.lambdaQuery(FlowBizStep.class);
        FlowBizStep currentStep = queryStep.andEq(FlowBizStep::getFlowBizId,currentFlowBiz.getId())
                .andEq(FlowBizStep::getStepNo,currentFlowBiz.getCurrentStep())
                .single();
        if (null == currentStep){
            return false;
        }
        //判断步骤状态
        if (currentFlowBiz.getCurrentStep().equals(currentFlowBiz.getTotalStep())
                || FlowBizStatusEnum.PASS.getCode() != status){
            //当前步骤就是最后一步 或 步骤状态不为 通过状态，流程主表更新状态
            currentFlowBiz.setCurrentStatus(status);
            //同时更新业务表状态
            Map<String,Object> bizStatusInfo = new HashMap<>();
            bizStatusInfo.put("tableName",currentFlowBiz.getBizTable());
            bizStatusInfo.put("tableCol",currentFlowBiz.getBizStatusCol());
            if (FlowBizStatusEnum.PASS.getCode() == status){
                bizStatusInfo.put("status",currentFlowBiz.getBizPassStatus());
            }else if (FlowBizStatusEnum.BACK.getCode() == status) {
                bizStatusInfo.put("status",currentFlowBiz.getBizBackStatus());
            }else {
                bizStatusInfo.put("status",FlowBizStatusEnum.REJECT.getCode());
            }
            bizStatusInfo.put("bizId",currentFlowBiz.getBizId());
            this.sqlManager.update("flowBiz.updateBizTableStatus",bizStatusInfo);
        } else{
            //流程主表更新步数
            LambdaQuery<FlowStep> queryStepOrg = sqlManager.lambdaQuery(FlowStep.class);
            FlowStep orgNextStep = queryStepOrg.andEq(FlowStep::getFlowId,currentFlowBiz.getFlowId())
                    .andEq(FlowStep::getSort,currentFlowBiz.getCurrentStep()+1).single();
            if (null == orgNextStep){
                return false;
            }
            currentFlowBiz.setCurrentStep(currentFlowBiz.getCurrentStep()+1);
            currentFlowBiz.setCurrentStepMember(orgNextStep.getStepMember());
            currentFlowBiz.setCurrentStepName(orgNextStep.getStepName());
        }
        int bizNum = flowService.updateFlowBiz(currentFlowBiz);
        if (0 == bizNum){
            return false;
        }
        //更新业务流程明细表数据
        currentStep.setStepStatus(status);
        currentStep.setStepComment(comment);
        int stepNum = flowService.updateFlowBizStep(currentStep);
        if (0 == stepNum) {
            return false;
        }
        return true;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public boolean nextStep(Long bizId, String flowFlag, int status, String comment){
        if (null == bizId || StringUtil.isEmpty(flowFlag)){
            return false;
        }
        //获取当前流程
        LambdaQuery<FlowBiz> query = sqlManager.lambdaQuery(FlowBiz.class);
        FlowBiz currentFlowBiz = query.andEq(FlowBiz::getFlowFlag,flowFlag)
                .andEq(FlowBiz::getBizId,bizId)
                .andEq(FlowBiz::getIsDelete,IsDeleteEnum.NOTDELETE.getCode())
                .single();
        if (null == currentFlowBiz){
            return false;
        }
        LambdaQuery<FlowBizStep> queryStep = sqlManager.lambdaQuery(FlowBizStep.class);
        FlowBizStep currentStep = queryStep.andEq(FlowBizStep::getFlowBizId,currentFlowBiz.getId())
                .andEq(FlowBizStep::getStepNo,currentFlowBiz.getCurrentStep())
                .single();
        if (null == currentStep){
            return false;
        }
        //判断步骤状态
        if (currentFlowBiz.getCurrentStep().equals(currentFlowBiz.getTotalStep())
                || FlowBizStatusEnum.PASS.getCode() != status){
            //当前步骤就是最后一步 或 步骤状态不为 通过状态，流程主表更新状态
            currentFlowBiz.setCurrentStatus(status);
            //同时更新业务表状态
            Map<String,Object> bizStatusInfo = new HashMap<>();
            bizStatusInfo.put("tableName",currentFlowBiz.getBizTable());
            bizStatusInfo.put("tableCol",currentFlowBiz.getBizStatusCol());
            if (FlowBizStatusEnum.PASS.getCode() == status){
                bizStatusInfo.put("status",currentFlowBiz.getBizPassStatus());
            }else if (FlowBizStatusEnum.BACK.getCode() == status) {
                bizStatusInfo.put("status",currentFlowBiz.getBizBackStatus());
            }else {
                bizStatusInfo.put("status",FlowBizStatusEnum.REJECT.getCode());
            }
            bizStatusInfo.put("bizId",currentFlowBiz.getBizId());
            this.sqlManager.update("flowBiz.updateBizTableStatus",bizStatusInfo);
        } else{
            //流程主表更新步数
            LambdaQuery<FlowStep> queryStepOrg = sqlManager.lambdaQuery(FlowStep.class);
            FlowStep orgNextStep = queryStepOrg.andEq(FlowStep::getFlowId,currentFlowBiz.getFlowId())
                    .andEq(FlowStep::getSort,currentFlowBiz.getCurrentStep()+1).single();
            if (null == orgNextStep){
                return false;
            }
            currentFlowBiz.setCurrentStep(currentFlowBiz.getCurrentStep()+1);
            currentFlowBiz.setCurrentStepMember(orgNextStep.getStepMember());
            currentFlowBiz.setCurrentStepName(orgNextStep.getStepName());
        }
        int bizNum = flowService.updateFlowBiz(currentFlowBiz);
        if (0 == bizNum){
            return false;
        }
        //更新业务流程明细表数据
        currentStep.setStepStatus(status);
        currentStep.setStepComment(comment);
        int stepNum = flowService.updateFlowBizStep(currentStep);
        if (0 == stepNum) {
            return false;
        }
        return true;
    }

    @Override
    @EntityCommonValue(operation = "CREATE")
    public int insertFlowBiz(FlowBiz flowBiz){
        return this.sqlManager.insert(flowBiz,true);
    }

    @Override
    @EntityCommonValue(operation = "UPDATE")
    public int updateFlowBiz(FlowBiz flowBiz){
        return this.sqlManager.updateTemplateById(flowBiz);
    }

    @Override
    public int insertFlowBizStep(FlowBizStep flowBizStep){
        return this.sqlManager.insert(flowBizStep);
    }

    @Override
    @EntityCommonValue(operation = "UPDATE")
    public int updateFlowBizStep(FlowBizStep flowBizStep){
        return this.sqlManager.updateTemplateById(flowBizStep);
    }

    @Override
    public List<FlowBizStepVo> getFlowBizStep(Long bizId, String flowFlag){
        //获取当前流程
        LambdaQuery<FlowBiz> query = sqlManager.lambdaQuery(FlowBiz.class);
        FlowBiz currentFlowBiz = query.andEq(FlowBiz::getFlowFlag,flowFlag)
                .andEq(FlowBiz::getBizId,bizId)
                .andEq(FlowBiz::getIsDelete,IsDeleteEnum.NOTDELETE.getCode())
                .orderBy("update_time desc")
                .single();
        if (null == currentFlowBiz){
            return null;
        }
        LambdaQuery<FlowBizStep> queryStep = sqlManager.lambdaQuery(FlowBizStep.class);
        List<FlowBizStep> stepList = queryStep.andEq(FlowBizStep::getFlowBizId,currentFlowBiz.getId())
                .orderBy("step_no asc").select();
        if (0 == stepList.size()){
            return null;
        }
        List<FlowBizStepVo> voList = new ArrayList<>(stepList.size());
        stepList.forEach(item -> {
            FlowBizStepVo flowBizStepVo = new FlowBizStepVo();
            flowBizStepVo.setId(item.getId());
            flowBizStepVo.setFlowBizId(item.getFlowBizId());
            flowBizStepVo.setStepNo(item.getStepNo());
            flowBizStepVo.setStepStatus(item.getStepStatus());
            flowBizStepVo.setStepComment(item.getStepComment());
            if (null != item.getUpdateBy()){
                UserSingleDetailQueryDTO userSingleDetailQueryDTO = new UserSingleDetailQueryDTO();
                userSingleDetailQueryDTO.setUserId(item.getUpdateBy());
                flowBizStepVo.setCheckName(adminUserRemoteService.singleDetailQuery(userSingleDetailQueryDTO).getData().getName());
                flowBizStepVo.setCheckTime(item.getUpdateTime());
            }
            flowBizStepVo.setStepName(item.getStepName());
            flowBizStepVo.setStepMember(item.getStepMember());
            voList.add(flowBizStepVo);
        });
        return voList;
    }

    @Override
    public List<FlowBizStepVo> getFlowBizStep(Long bizFlowId){
        //获取当前流程
        LambdaQuery<FlowBiz> query = sqlManager.lambdaQuery(FlowBiz.class);
        FlowBiz currentFlowBiz = query.andEq(FlowBiz::getId,bizFlowId).single();
        if (null == currentFlowBiz){
            return null;
        }
        LambdaQuery<FlowBizStep> queryStep = sqlManager.lambdaQuery(FlowBizStep.class);
        List<FlowBizStep> stepList = queryStep.andEq(FlowBizStep::getFlowBizId,currentFlowBiz.getId())
                .orderBy("step_no asc").select();
        if (0 == stepList.size()){
            return null;
        }
        List<FlowBizStepVo> voList = new ArrayList<>(stepList.size());
        //todo 获取发起人信息
        FlowBizStepVo flowCreateStep =  getFlowCreator(currentFlowBiz);
        flowCreateStep.setStepStatus(88);
        voList.add(flowCreateStep);

        stepList.forEach(item -> {
            FlowBizStepVo flowBizStepVo = new FlowBizStepVo();
            flowBizStepVo.setId(item.getId());
            flowBizStepVo.setFlowBizId(item.getFlowBizId());
            flowBizStepVo.setStepNo(item.getStepNo());
            flowBizStepVo.setStepStatus(item.getStepStatus());
            flowBizStepVo.setStepComment(item.getStepComment());
            flowBizStepVo.setStepUser(item.getStepUser());
            flowBizStepVo.setCcUser(item.getCcUser());
            flowBizStepVo.setStepUserName(item.getStepUserName());
            flowBizStepVo.setCcUserName(item.getCcUserName());
            flowBizStepVo.setESignature(item.getESignature());
            if (null != item.getUpdateBy()){
                UserSingleDetailQueryDTO userSingleDetailQueryDTO = new UserSingleDetailQueryDTO();
                userSingleDetailQueryDTO.setUserId(item.getUpdateBy());
                flowBizStepVo.setCheckName(adminUserRemoteService.singleDetailQuery(userSingleDetailQueryDTO).getData().getName());
                flowBizStepVo.setCheckTime(item.getUpdateTime());
            }
            flowBizStepVo.setStepName(item.getStepName());
            flowBizStepVo.setStepMember(item.getStepMember());
            voList.add(flowBizStepVo);
        });
        return voList;
    }

    @Override
    public FlowBiz getFlowBiz(Long flowId){
        FlowBiz currentFlowBiz = sqlManager.lambdaQuery(FlowBiz.class)
                .andEq(FlowBiz::getId, flowId)
                .andEq(FlowBiz::getIsDelete, IsDeleteEnum.NOTDELETE.getCode())
                .single();
        return currentFlowBiz;
    }

    /******************************************************** 自定义流程升级部分 ********************************************************/

    @Override
    public List<FlowStep> showStepList(String flowType,String flowFlag){
        AdminUserVO adminUserVO = AdminUserContext.getUser();
        //查询当前可用流程
        FlowDefinition flowDefinition = sqlManager.lambdaQuery(FlowDefinition.class)
                .andEq(FlowDefinition::getFlowFlag, flowFlag)
                .andEq(FlowDefinition::getStatus, FlowStatusEnum.USABLE.getCode())
                .andEq(FlowDefinition::getIsDelete, IsDeleteEnum.NOTDELETE.getCode())
                .single();
        if (null == flowDefinition) {
            throw new CustomException("未找到标准流程");
        }
        List<FlowStep> stepList = sqlManager.lambdaQuery(FlowStep.class)
                .andEq(FlowStep::getFlowId, flowDefinition.getId())
                .orderBy("sort asc")
                .select();
        if (0 == stepList.size()) {
            throw new CustomException("该标准流程没有设置步骤");
        }
        if (FlowBizTypeEnum.STANDARD.getCode().equals(flowType)){
            for (FlowStep flowStep:stepList){
                // 添加当前用户ID及用户名称（String类型，可多用户，格式aaa，bbb）
                List<Long> userIdList = getUserIdList(Long.valueOf(flowStep.getStepMember()), adminUserVO.getDeptid());
                flowStep.setStepUser(StringUtils.join(userIdList, ","));
                flowStep.setStepUserName(getUserNames(userIdList));
            }
            return stepList;
        }else if (FlowBizTypeEnum.CUSTOMIZATION.getCode().equals(flowType)){
            List<FlowStep> lastOneStep = new ArrayList<>();
            lastOneStep.add(stepList.get(stepList.size()-1));
            // 添加当前用户ID及用户名称（String类型，可多用户，格式aaa，bbb）
            List<Long> userIdList = getUserIdList(Long.valueOf(stepList.get(stepList.size()-1).getStepMember()), adminUserVO.getDeptid());
            lastOneStep.get(0).setStepUser(StringUtils.join(userIdList, ","));
            lastOneStep.get(0).setStepUserName(getUserNames(userIdList));
            return lastOneStep;
        }else {
            throw new CustomException("获取流程步骤出错，请联系管理员");
        }
    }

    @Transactional(rollbackFor = Exception.class)
    @Override
    public Long startFlowCustomizationOrStandard(Long bizId, String bizTable, String bizStatusCol, Integer bizBackStatus,
                                                 Integer bizPassStatus, Integer bizRejectStatus, Integer bizRevocationStatus,
                                                 String flowFlag, Long deptId, List<FlowBizStep> stepList, String flowType){
        if (StringUtils.isEmpty(flowType) || FlowBizTypeEnum.STANDARD.getCode().equals(flowType)) {
            return startFlowUpgrade(bizId,bizTable,bizStatusCol,bizBackStatus,bizPassStatus,bizRejectStatus,bizRevocationStatus,
                    flowFlag,deptId);
        }else {
            return startFlowCustomization(bizId,bizTable,bizStatusCol,bizBackStatus,bizPassStatus,bizRejectStatus,bizRevocationStatus,
                    flowFlag,deptId,stepList);
        }

    }


    @Transactional(rollbackFor = Exception.class)
    @Override
    public Long startFlowCustomization(Long bizId, String bizTable, String bizStatusCol,
                                 Integer bizBackStatus, Integer bizPassStatus, Integer bizRejectStatus,
                                 Integer bizRevocationStatus,String flowFlag, Long deptId, List<FlowBizStep> stepList) {
        if (null == deptId) {
            throw new CustomException("开启流程失败！");
        }
        if (null == bizId || StringUtil.isEmpty(bizTable) || StringUtil.isEmpty(flowFlag)) {
            throw new CustomException("开启流程失败！");
        }
        //查询当前可用流程
        FlowDefinition flowDefinition = sqlManager.lambdaQuery(FlowDefinition.class)
                .andEq(FlowDefinition::getFlowFlag, flowFlag)
                .andEq(FlowDefinition::getStatus, FlowStatusEnum.USABLE.getCode())
                .andEq(FlowDefinition::getIsDelete, IsDeleteEnum.NOTDELETE.getCode())
                .single();
        if (null == flowDefinition) {
            throw new CustomException("无可用标准流程，开启流程失败！");
        }
        //新增主流程
        FlowBiz flowBiz = this.saveFlowBizCustomization(flowDefinition,stepList,bizId,bizTable,bizStatusCol,
                bizBackStatus,bizPassStatus,bizRejectStatus,bizRevocationStatus);
        //新增流程步骤，更新流程用户列表
        this.saveBizFlowStepCustomization(deptId, stepList, flowBiz);
        return flowBiz.getId();
    }

    private FlowBizStepVo getFlowCreator(FlowBiz currentFlowBiz) {
        FlowBizStepVo vo= new FlowBizStepVo();
        //根据不同业务查不同的表,获取发起人以及创建时间
        Long creator = getaLong(currentFlowBiz, vo);
        //统一获取用户信息
        if(null != creator){
            vo.setStepUserName(TranslateUtil.getUserName(creator));
        }
        vo.setStepName("流程发起");
        return vo;
    }

    private Long getaLong(FlowBiz currentFlowBiz, FlowBizStepVo vo) {
        String flowFlag = currentFlowBiz.getFlowFlag();
        Long creator = null;
        if(StringUtil.equalsIgnoreCase(FlowFlagEnum.MAKING_PLAN.getCode(), flowFlag)){
            //计划拟制
            PlanInfo planInfo = planInfoService.selectById(currentFlowBiz.getBizId());
            if(null != planInfo){
                creator = planInfo.getCreateBy();
                vo.setCheckTime(planInfo.getCreateTime());
            }
        }else if(StringUtil.equalsIgnoreCase(FlowFlagEnum.APPRAISAL_MANAGEMENT.getCode(), flowFlag)){
            //鉴定管理
            IdentInfo identInfo = iIdentInfoService.selectById(currentFlowBiz.getBizId());
            if(null != identInfo){
                creator = identInfo.getCreateBy();
                vo.setCheckTime(identInfo.getCreateTime());
            }
        }else if(StringUtil.equalsIgnoreCase(FlowFlagEnum.PROJECT_FINISH_REVIEW.getCode(), flowFlag) ||
                StringUtil.equalsIgnoreCase(FlowFlagEnum.PROJECT_OPEN_DRAFT.getCode(), flowFlag) ||
                StringUtil.equalsIgnoreCase(FlowFlagEnum.PROJECT_OPEN_REVIEW.getCode(), flowFlag) ||
                StringUtil.equalsIgnoreCase(FlowFlagEnum.PROJECT_OPEN_SUBMIT.getCode(), flowFlag) ||
                StringUtil.equalsIgnoreCase(FlowFlagEnum.PROJECT_FINISH_APPLY.getCode(), flowFlag) ||
                StringUtil.equalsIgnoreCase(FlowFlagEnum.PROJECT_FINISH_SUBMIT.getCode(), flowFlag) ||
                StringUtil.equalsIgnoreCase(FlowFlagEnum.PROJECT_DELAY_CHECK.getCode(), flowFlag) ||
                StringUtil.equalsIgnoreCase(FlowFlagEnum.PROJECT_STOP_CHECK.getCode(), flowFlag) ){


            //项目结题评审审核,项目开题拟制审核,项目开题评审审核，项目开题提报审核，项目结题申请审核,项目结题提报审核,项目延期审核,项目终止审核
            ProjectMain projectMain = projectMainService.selectById(currentFlowBiz.getBizId());
            if(null != projectMain){
                creator = projectMain.getCreateBy();
                vo.setCheckTime(projectMain.getCreateTime());
            }
        }else if(StringUtil.equalsIgnoreCase(FlowFlagEnum.PROJECT_OPENING.getCode(), flowFlag) ||
                StringUtil.equalsIgnoreCase(FlowFlagEnum.PROJECT_DELAY.getCode(), flowFlag) ||
                StringUtil.equalsIgnoreCase(FlowFlagEnum.PROJECT_CONCLUSION.getCode(), flowFlag)){
            //项目开题，项目延期,项目结题
            ProjectInfo projectInfo = projectInfoService.selectById(currentFlowBiz.getBizId());
            if(null != projectInfo){
                creator = projectInfo.getCreateBy();
                vo.setCheckTime(projectInfo.getCreateTime());
            }
        }else if(StringUtil.equalsIgnoreCase(FlowFlagEnum.MAJOR_NODE.getCode(), flowFlag)){
            //重大节点
            ProjectNode projectNode = projectNodeService.selectById(currentFlowBiz.getBizId());
            if(null != projectNode){
                creator = projectNode.getCreateBy();
                vo.setCheckTime(projectNode.getCreateTime());
            }
        }else if(StringUtil.equalsIgnoreCase(FlowFlagEnum.FUND_EXPENDITURE.getCode(), flowFlag)){
            //经费开支
            ProjectFund projectFund = projectFundService.selectById(currentFlowBiz.getBizId());
            if(null != projectFund){
                creator = projectFund.getCreateBy();
                vo.setCheckTime(projectFund.getCreateTime());
            }
        }else if(StringUtil.equalsIgnoreCase(FlowFlagEnum.BUDGET_MANAGEMENT.getCode(), flowFlag)){
            //预算管理
            FundBudget fundBudget = fundBudgetService.selectById(currentFlowBiz.getBizId());
            if(null != fundBudget){
                creator = fundBudget.getCreateBy();
                vo.setCheckTime(fundBudget.getCreateTime());
            }
        }else if(StringUtil.equalsIgnoreCase(FlowFlagEnum.ACHIEVEMENT_MANAGEMENT.getCode(), flowFlag)){
            //成果管理
            STAward stAward = stAwardService.selectById(currentFlowBiz.getBizId());
            if(null != stAward){
                creator = stAward.getCreateBy();
                vo.setCheckTime(stAward.getCreateTime());
            }
        }else if(StringUtil.equalsIgnoreCase(FlowFlagEnum.FUND_APPLY.getCode(), flowFlag)){
            //经费请领
            FundApply fundApply = fundApplyService.selectById(currentFlowBiz.getBizId());
            if(null != fundApply){
                creator = fundApply.getCreateBy();
                vo.setCheckTime(fundApply.getCreateTime());
            }
        }else if(StringUtil.equalsIgnoreCase(FlowFlagEnum.PROJECT_EXPENSE_REQUEST.getCode(), flowFlag)){
            //项目经费支出申请流程
            ProjectFundExpenseRequest projectFundExpenseRequest  = projectFERService.selectById(currentFlowBiz.getBizId());
            if(null != projectFundExpenseRequest){
                creator = projectFundExpenseRequest.getCreateBy();
                vo.setCheckTime(projectFundExpenseRequest.getCreateTime());
            }
        }else if(StringUtil.equalsIgnoreCase(FlowFlagEnum.PROJECT_BUDGET_MANAGE.getCode(), flowFlag)){
            //项目预算管理
            BudgetManage budgetManage = budgetManageService.selectById(currentFlowBiz.getBizId());
            if(null != budgetManage){
                creator = budgetManage.getCreateBy();
                vo.setCheckTime(budgetManage.getCreateTime());
            }
        }else if(StringUtil.equalsIgnoreCase(FlowFlagEnum.OUT_COOP.getCode(), flowFlag)){
            // 外协合作管理
            OutCoop outCoop = outCoopService.selectById(currentFlowBiz.getBizId());
            if(null != outCoop){
                creator = outCoop.getCreateBy();
                vo.setCheckTime(outCoop.getCreateTime());
            }
        } else if(StringUtil.equalsIgnoreCase(FlowFlagEnum.OUT_CONTRACT.getCode(), flowFlag)){
            // 外协合同管理
            OutContract outContract = outContractService.selectById(currentFlowBiz.getBizId());
            if(null != outContract){
                creator = outContract.getCreateBy();
                vo.setCheckTime(outContract.getCreateTime());
            }
        }else if(StringUtil.equalsIgnoreCase(FlowFlagEnum.RESULT_INFO.getCode(), flowFlag)){
            // 成果申请管理
            ResultInfo resultInfo = resultInfoService.selectById(currentFlowBiz.getBizId());
            if(null != resultInfo){
                creator = resultInfo.getCreateBy();
                vo.setCheckTime(resultInfo.getCreateTime());
            }
        }else if(StringUtil.equalsIgnoreCase(FlowFlagEnum.RESULT_BORROW.getCode(), flowFlag)){
            // 成果借阅管理
            ResultBorrow resultBorrow = resultBorrowService.selectById(currentFlowBiz.getBizId());
            if(null != resultBorrow){
                creator = resultBorrow.getCreateBy();
                vo.setCheckTime(resultBorrow.getCreateTime());
            }
        }
        return creator;
        }

    /******************************************************** 流程升级部分 ********************************************************/


    /*  业务流程逻辑处理  */
    @Transactional(rollbackFor = Exception.class)
    @Override
    public Long startFlowUpgrade(Long bizId, String bizTable, String bizStatusCol,
                                 Integer bizBackStatus, Integer bizPassStatus, Integer bizRejectStatus,
                                 Integer bizRevocationStatus,String flowFlag, Long deptId) {
        if (null == deptId) {
            throw new CustomException("开启流程失败！");
        }
        if (null == bizId || StringUtil.isEmpty(bizTable) || StringUtil.isEmpty(flowFlag)) {
            throw new CustomException("开启流程失败！");
        }
        //查询当前可用流程
        FlowDefinition flowDefinition = sqlManager.lambdaQuery(FlowDefinition.class)
                .andEq(FlowDefinition::getFlowFlag, flowFlag)
                .andEq(FlowDefinition::getStatus, FlowStatusEnum.USABLE.getCode())
                .andEq(FlowDefinition::getIsDelete, IsDeleteEnum.NOTDELETE.getCode())
                .single();
        if (null == flowDefinition) {
            throw new CustomException("无可用标准流程，开启流程失败！");
        }
        List<FlowStep> stepList = sqlManager.lambdaQuery(FlowStep.class)
                .andEq(FlowStep::getFlowId, flowDefinition.getId())
                .orderBy("sort asc")
                .select();
        if (0 == stepList.size()) {
            throw new CustomException("开启流程失败！");
        }
        //新增主流程
        FlowBiz flowBiz = this.saveFlowBiz(flowDefinition,stepList,bizId,bizTable,bizStatusCol,bizBackStatus,bizPassStatus,bizRejectStatus,bizRevocationStatus,deptId);
        //新增流程步骤，更新流程用户列表
        this.saveBizFlowStep(deptId, stepList, flowBiz);
        return flowBiz.getId();
    }


    /**
     * 流程下一步 （升级版）
     * @param flowBizModel 请求参数
     * @return
     */
    @Transactional(rollbackFor = Exception.class)
    @Override
    public boolean nextStepUpgrade(FlowBizModel flowBizModel) {
        if (null == flowBizModel.getBizFlowId()) {
            throw new CustomException("流程id为空，操作失败！");
        }
        //获取当前流程
        FlowBiz currentFlowBiz = sqlManager.lambdaQuery(FlowBiz.class)
                .andEq(FlowBiz::getId, flowBizModel.getBizFlowId())
                .andEq(FlowBiz::getIsDelete, IsDeleteEnum.NOTDELETE.getCode())
                .single();
        if (null == currentFlowBiz) {
            throw new CustomException("当前流程不存在，操作失败！");
        }
        List<FlowBizStep> stepList = sqlManager.lambdaQuery(FlowBizStep.class)
                .andEq(FlowBizStep::getFlowBizId, currentFlowBiz.getId())
                .orderBy("step_no asc")
                .select();
        if (0 == stepList.size()) {
            throw new CustomException("当前流程步骤为空，操作失败！");
        }
        FlowBizStep currentStep = sqlManager.lambdaQuery(FlowBizStep.class)
                .andEq(FlowBizStep::getFlowBizId, currentFlowBiz.getId())
                .andEq(FlowBizStep::getStepNo, currentFlowBiz.getCurrentStep())
                .single();
        if (null == currentStep) {
            throw new CustomException("当前当前步骤不存在，操作失败！");
        }
        //流程变动操作
        this.flowChange(stepList,currentStep,flowBizModel.getDeleteId(), flowBizModel.getAddUserIds(), flowBizModel.getAddStepName());
        //流程变动操作后，需重新查询新的流程步骤
        List<FlowBizStep> newStepList = sqlManager.lambdaQuery(FlowBizStep.class)
                .andEq(FlowBizStep::getFlowBizId, currentFlowBiz.getId())
                .orderBy("step_no asc")
                .select();
        //判断步骤状态
        if (BooleanUtils.toBoolean(null == flowBizModel.getIsEarlyTerminate() ? 0 : flowBizModel.getIsEarlyTerminate())) {
            //若流程提前终止
            //删除后续不走
            earlyTerminateFlow(currentFlowBiz,newStepList,currentStep,flowBizModel);
            //更新业务表状态
            finalFlowStep(currentFlowBiz,currentFlowBiz.getBizPassStatus());
            //推动流程下一步/更新主流程状态
            flowBizNext(currentFlowBiz,newStepList,currentStep, flowBizModel,true);
        } else if (FlowBizStatusEnum.BACK.getCode() ==  flowBizModel.getStatus()){
            //退休修改操作
            goBackFlowStep(currentFlowBiz,stepList,currentStep,flowBizModel.getDeptId(),flowBizModel.getBizDataCreateBy());
            //更新业务表状态
            finalFlowStep(currentFlowBiz,currentFlowBiz.getBizBackStatus());
            //推动流程下一步/更新主流程状态
            flowBizNext(currentFlowBiz,newStepList,currentStep, flowBizModel,true);
        }else if (FlowBizStatusEnum.REJECT.getCode() ==  flowBizModel.getStatus()){
            finalFlowStep(currentFlowBiz,currentFlowBiz.getBizRejectStatus());
            flowBizNext(currentFlowBiz,newStepList,currentStep, flowBizModel,true);
        }else if (currentFlowBiz.getCurrentStep().equals(stepList.size())){
            if (FlowBizStatusEnum.TURN.getCode() ==  flowBizModel.getStatus()) {
                throw new CustomException("最终步骤不可转办，操作失败！");
            }
            finalFlowStep(currentFlowBiz,currentFlowBiz.getBizPassStatus());
            flowBizNext(currentFlowBiz,newStepList,currentStep, flowBizModel,true);
        }else {
            flowBizNext(currentFlowBiz,newStepList,currentStep, flowBizModel,false);
        }
        int stepNum = this.updateCurrentStep(currentStep,flowBizModel);
        if (0 == stepNum) {
            throw new CustomException("审核操作异常！");
        }
        this.updateFlowUser(currentFlowBiz);
        //记录流程步骤审核日志
        FlowBizStep currentStepNew = sqlManager.lambdaQuery(FlowBizStep.class)
                .andEq(FlowBizStep::getFlowBizId, currentFlowBiz.getId())
                .andEq(FlowBizStep::getStepNo, currentFlowBiz.getCurrentStep())
                .single();
        int logCount = flowStepLogService.insertFlowStepLog(currentFlowBiz.getId(),currentStep.getId(),currentStep.getStepName(),
                flowBizModel.getStatus(),flowBizModel.getComment(),flowBizModel.getCcUserIds(),currentStepNew.getESignature());
        if (logCount < 1) {
            throw new CustomException("审核操作日志记录异常！");
        }
        return true;
    }


    /**
     * 自定流程/标准流程   --- 退回修改重新提交
     * @param bizFlowId
     * @param stepList
     * @param flowType
     * @return
     */
    @Transactional(rollbackFor = Exception.class)
    @Override
    public int nextStepOnlyForBackCusOrBack(Long bizFlowId,List<FlowBizStep> stepList,String flowType){
        if (FlowBizTypeEnum.STANDARD.getCode().equals(flowType)) {
           return nextStepOnlyForBack(bizFlowId);
        }else {
           return nextStepOnlyForBack(bizFlowId,stepList);
        }
    }

    /**
     *
     * 退回修改流程一下步操作
     *
     * @param bizFlowId 主流程id
     * @return
     */
    @Transactional(rollbackFor = Exception.class)
    @Override
    public int nextStepOnlyForBack(Long bizFlowId){
        //获取当前主流程
        FlowBiz currentFlowBiz = sqlManager.lambdaQuery(FlowBiz.class).
                andEq(FlowBiz::getId, bizFlowId)
                .andEq(FlowBiz::getIsDelete, IsDeleteEnum.NOTDELETE.getCode())
                .single();

        //获取之前所有流程步骤
        List<FlowBizStep> stepLists = sqlManager.lambdaQuery(FlowBizStep.class)
                .andEq(FlowBizStep::getFlowBizId, currentFlowBiz.getId())
                .orderBy("step_no asc")
                .select();

        AdminUserVO adminUserVO = AdminUserContext.getUser();
        //查询该流程定义步骤，接入现有流程步骤的后面
        LambdaQuery<FlowStep> queryStep = sqlManager.lambdaQuery(FlowStep.class);
        List<FlowStep> stepList = queryStep.andEq(FlowStep::getFlowId, currentFlowBiz.getFlowId())
                .orderBy("sort asc").select();
        if (!CollectionUtils.isEmpty(stepList)) {
            AtomicInteger stepNum = new AtomicInteger();
            int size = stepLists.size();
            stepList.forEach(item -> {
                FlowBizStep flowBizStep = new FlowBizStep();
                flowBizStep.setFlowBizId(currentFlowBiz.getId());
                flowBizStep.setStepNo(size + item.getSort());
                flowBizStep.setStepMember(item.getStepMember());
                flowBizStep.setStepName(item.getStepName());
                List<Long> userIdList = getUserIdList(Long.valueOf(item.getStepMember()), adminUserVO.getDeptid());
                flowBizStep.setStepUser(StringUtils.join(userIdList, ","));
                flowBizStep.setStepUserName(getUserNames(userIdList));
//                flowBizStep.setStepUser(item.getStepUser());
//                flowBizStep.setStepUserName(item.getStepUserName());
                stepNum.addAndGet(sqlManager.insertTemplate(flowBizStep));
                stepLists.add(flowBizStep);
            });
            String member = stepList.get(0).getStepMember();
            List<Long> userIdList = getUserIdList(Long.valueOf(member), adminUserVO.getDeptid());
            currentFlowBiz.setCurrentStepUser(StringUtils.join(userIdList, ","));
            currentFlowBiz.setCurrentStepUserName(getUserNames(userIdList));

            currentFlowBiz.setCurrentStepMember(stepList.get(0).getStepMember());
            currentFlowBiz.setCurrentStepName(stepList.get(0).getStepName());
            //重新整理流程相关用户
            StringBuilder flowUserIds = new StringBuilder();
            stepLists.forEach(item -> {
                if (!StringUtils.isEmpty(flowUserIds)) {
                    flowUserIds.append(",");
                }
                flowUserIds.append(item.getStepUser());
                if (!StringUtils.isEmpty(item.getCcUser())) {
                    flowUserIds.append(",").append(item.getCcUser());
                }
            });
            //更新流程相关用户
            currentFlowBiz.setFlowUser(flowUserIds.toString());
        }

        //更新主流程相关信息
        currentFlowBiz.setCurrentStatus(FlowBizStatusEnum.CHECK.getCode());
        currentFlowBiz.setCurrentStep(currentFlowBiz.getCurrentStep() + 1);
        //数据重新提交后，流程内不可撤回
        currentFlowBiz.setBeforeStepUser(-1L);
        return sqlManager.updateTemplateById(currentFlowBiz);
    }

    /**
     * 自定流程/标准流程   --- 退回修改重新提交
     * @param bizFlowId
     * @param stepList
     * @param flowType
     * @return
     */
    @Transactional(rollbackFor = Exception.class)
    @Override
    public int nextStepOnlyForBackPlan(Long bizFlowId,String flowType,List<FlowBizStep> stepList){
        // 更新主表flowtype
        FlowBiz currentFlowBiz = new FlowBiz();
        currentFlowBiz.setId(bizFlowId);
        currentFlowBiz.setFlowType(flowType);
        sqlManager.updateTemplateById(FlowBiz.class, currentFlowBiz);
        if (FlowBizTypeEnum.STANDARD.getCode().equals(flowType)) {
            return nextStepOnlyForBack(bizFlowId);
        }else {
            return nextStepOnlyForBackPlanDetail(bizFlowId,stepList);
        }
    }

    /**
     *
     * 退回修改流程一下步操作
     *
     * @param bizFlowId 主流程id
     * @return
     */
    @Transactional(rollbackFor = Exception.class)
    int nextStepOnlyForBackPlanDetail(Long bizFlowId, List<FlowBizStep> stepList){
        //获取当前主流程
        FlowBiz currentFlowBiz = sqlManager.lambdaQuery(FlowBiz.class).
                andEq(FlowBiz::getId, bizFlowId)
                .andEq(FlowBiz::getIsDelete, IsDeleteEnum.NOTDELETE.getCode())
                .single();
        //获取之前所有流程步骤
        List<FlowBizStep> stepLists = sqlManager.lambdaQuery(FlowBizStep.class)
                .andEq(FlowBizStep::getFlowBizId, currentFlowBiz.getId())
                .orderBy("step_no asc")
                .select();

        AtomicInteger stepNum = new AtomicInteger();
        Integer size = stepLists.size();
        for (int i = 0 ; i < stepList.size(); i ++) {
            FlowBizStep flowBizStep = new FlowBizStep();
            flowBizStep.setFlowBizId(currentFlowBiz.getId());
            flowBizStep.setStepNo(size + i + 1);
            flowBizStep.setStepMember(stepList.get(i).getStepMember());
            flowBizStep.setStepName(stepList.get(i).getStepName());
            flowBizStep.setStepUser(stepList.get(i).getStepUser());
            flowBizStep.setStepUserName(stepList.get(i).getStepUserName());
            stepNum.addAndGet(sqlManager.insertTemplate(flowBizStep));
            stepLists.add(flowBizStep);
        }

        currentFlowBiz.setCurrentStepMember(stepList.get(0).getStepMember());
        currentFlowBiz.setCurrentStepName(stepList.get(0).getStepName());
        currentFlowBiz.setCurrentStepUser(stepList.get(0).getStepUser());
        currentFlowBiz.setCurrentStepUserName(stepList.get(0).getStepUserName());
        //更新主流程相关信息
        currentFlowBiz.setCurrentStatus(FlowBizStatusEnum.CHECK.getCode());
        currentFlowBiz.setCurrentStep(currentFlowBiz.getCurrentStep() + 1);

        //重新整理流程相关用户
        StringBuilder flowUserIds = new StringBuilder();
        stepLists.forEach(item -> {
            if (!StringUtils.isEmpty(flowUserIds)) {
                flowUserIds.append(",");
            }
            flowUserIds.append(item.getStepUser());
            if (!StringUtils.isEmpty(item.getCcUser())) {
                flowUserIds.append(",").append(item.getCcUser());
            }
        });
        //更新流程相关用户
        currentFlowBiz.setFlowUser(flowUserIds.toString());

        //数据重新提交后，流程内不可撤回
        currentFlowBiz.setBeforeStepUser(-1L);
        return sqlManager.updateTemplateById(currentFlowBiz);
    }


    /**
     *
     * 退回修改流程一下步操作
     *
     * @param bizFlowId 主流程id
     * @return
     */
    @Transactional(rollbackFor = Exception.class)
    @Override
    public int nextStepOnlyForBack(Long bizFlowId, List<FlowBizStep> stepList){
        if (null == bizFlowId) {
            throw new CustomException("开启流程失败，流程id缺失！");
        }
        if (CollectionUtils.isEmpty(stepList)) {
            throw new CustomException("开启流程失败，自定义流程步骤缺失！");
        }
        //获取当前主流程
        FlowBiz currentFlowBiz = sqlManager.lambdaQuery(FlowBiz.class).
                andEq(FlowBiz::getId, bizFlowId)
                .andEq(FlowBiz::getIsDelete, IsDeleteEnum.NOTDELETE.getCode())
                .single();
        //获取当前流程步骤
        FlowBizStep currentStep = sqlManager.lambdaQuery(FlowBizStep.class)
                .andEq(FlowBizStep::getFlowBizId, currentFlowBiz.getId())
                .andEq(FlowBizStep::getStepNo, currentFlowBiz.getCurrentStep())
                .single();
        //当前所有流程步骤
        List<FlowBizStep> currentStepList = sqlManager.lambdaQuery(FlowBizStep.class)
                .andEq(FlowBizStep::getFlowBizId, currentFlowBiz.getId())
                .orderBy("step_no asc")
                .select();
        //自定义流程步骤需 【删除】 原退回修改拼接的后续标准步骤
        List<FlowBizStep> deleteStepList = currentStepList.stream().filter(s -> s.getStepNo() > currentStep.getStepNo()).collect(Collectors.toList());
        deleteStepList.forEach(s ->{
            sqlManager.deleteById(FlowBizStep.class,s.getId());
        });

        //新增后续自定义流程步骤
        sqlManager.insertBatch(FlowBizStep.class,stepList);

        //重新查询流程
        List<FlowBizStep> newStepList = sqlManager.lambdaQuery(FlowBizStep.class)
                .andEq(FlowBizStep::getFlowBizId, currentFlowBiz.getId())
                .orderBy("step_no asc")
                .select();
        //重新整理流程相关用户
        StringBuilder flowUserIds = new StringBuilder();
        newStepList.forEach(item -> {
            if (!StringUtils.isEmpty(flowUserIds)) {
                flowUserIds.append(",");
            }
            flowUserIds.append(item.getStepUser());
            if (!StringUtils.isEmpty(item.getCcUser())) {
                flowUserIds.append(",").append(item.getStepUser());
            }
        });
        //推动流程一下步
        currentFlowBiz.setCurrentStatus(FlowBizStatusEnum.CHECK.getCode());
        currentFlowBiz.setCurrentStep(stepList.get(0).getStepNo());
        currentFlowBiz.setCurrentStepMember(stepList.get(0).getStepMember());
        currentFlowBiz.setCurrentStepName(stepList.get(0).getStepName());
        currentFlowBiz.setCurrentStepUser(stepList.get(0).getStepUser());
        currentFlowBiz.setCurrentStepUserName(stepList.get(0).getStepUserName());
        //更新流程相关用户
        currentFlowBiz.setFlowUser(flowUserIds.toString());
        return sqlManager.updateTemplateById(currentFlowBiz);
    }


    /**
     *
     * 流程审核撤回
     *
     * @param flowBizId 主流程id
     * @param stepId 撤回流程步骤id
     * @return
     */
    @Transactional(rollbackFor = Exception.class)
    @Override
    public boolean revocation(Long flowBizId, Long stepId) {
        List<FlowBizStep> stepList = sqlManager.lambdaQuery(FlowBizStep.class)
                .andEq(FlowBizStep::getFlowBizId, flowBizId)
                .orderBy("step_no asc").select();
        FlowBizStep currentStep = stepList.stream().filter(s -> s.getId().equals(stepId)).findAny().orElse(null);
        if (null != currentStep) {
            if (null != currentStep.getStepStatus()) {
                throw new CustomException("当前步骤已审核不可撤回！");
            }else {
                FlowBizStep revocationStep = stepList.stream().filter(s -> s.getStepNo().equals(currentStep.getStepNo() -1)).findAny().orElse(null);
                //撤回后，查找撤回步骤的前一位操作人，记为流程可撤回操作人
                FlowBizStep beforeStep = stepList.stream().filter(s -> s.getStepNo().equals(currentStep.getStepNo() -2)).findAny().orElse(null);
                if (null != revocationStep) {
                    AdminUserVO adminUserVO = AdminUserContext.getUser();
                    if (adminUserVO.getId().toString().equals(revocationStep.getStepUser())) {
                        //记录流程步骤审核日志
                        flowStepLogService.insertFlowStepLog(revocationStep.getFlowBizId(),revocationStep.getId(),revocationStep.getStepName(),
                                FlowBizStatusEnum.REVOCATION.getCode(), null,null,null);
                        revocationStep.setStepStatus(null);
                        revocationStep.setStepComment(null);
                        revocationStep.setCcUserName(null);
                        revocationStep.setCcUserName(null);
                        revocationStep.setUpdateBy(adminUserVO.getId());
                        revocationStep.setUpdateTime(new Date());
                        sqlManager.updateById(revocationStep);
                        FlowBiz flowBiz = new FlowBiz();
                        flowBiz.setId(flowBizId);
                        flowBiz.setCurrentStepUser(revocationStep.getStepUser());
                        flowBiz.setCurrentStepUserName(revocationStep.getStepUserName());
                        flowBiz.setCurrentStatus(FlowBizStatusEnum.CHECK.getCode());
                        flowBiz.setCurrentStepName(revocationStep.getStepUserName());
                        flowBiz.setCurrentStepMember(revocationStep.getStepMember());
                        flowBiz.setCurrentStep(revocationStep.getStepNo());
                        if (null != beforeStep && !beforeStep.getStepStatus().equals(FlowBizStatusEnum.BACK.getCode())) {
                            flowBiz.setBeforeStepUser(Long.valueOf(beforeStep.getStepUser()));
                        }else {
                            flowBiz.setBeforeStepUser(-1L);
                        }
                        sqlManager.updateTemplateById(flowBiz);
                        updateFlowUser(flowBiz);
                        return true;
                    }else {
                        throw new CustomException("非该步骤审核用户不可撤回！");
                    }
                }
            }
        }
        return false;
    }


    /**************************************************** 开启流程相关方法 ****************************************************/


    /**
     *
     * 新增业务审核主流程
     *
     * @param flowDefinition 流程定义
     * @param stepList 流程定义步骤
     * @param bizId 业务数据id
     * @param bizTable 业务表名
     * @param bizStatusCol 业务表状态字段名
     * @param bizBackStatus 业务数据退回修改状态值
     * @param bizPassStatus 业务数据通过状态值
     * @param deptId 业务数据所属部门
     * @return
     */
    private FlowBiz saveFlowBiz(FlowDefinition flowDefinition,List<FlowStep>stepList,Long bizId, String bizTable,
                                String bizStatusCol,Integer bizBackStatus,Integer bizPassStatus,Integer bizRejectStatus,
                                Integer bizRevocationStatus,Long deptId){
        //存入业务流程表
        FlowBiz flowBiz = new FlowBiz();
        flowBiz.setFlowId(flowDefinition.getId());
        flowBiz.setBizId(bizId);
        flowBiz.setFlowName(flowDefinition.getFlowName());
        flowBiz.setFlowFlag(flowDefinition.getFlowFlag());
        flowBiz.setFlowVersion(flowDefinition.getVersion());
        flowBiz.setBizTable(bizTable);
        flowBiz.setCurrentStep(stepList.get(0).getSort());
        flowBiz.setTotalStep(stepList.size());
        flowBiz.setCurrentStepName(stepList.get(0).getStepName());
        flowBiz.setCurrentStepMember(stepList.get(0).getStepMember());
        // 添加当前审核用户ID及用户名称（String类型，可多用户，格式aaa，bbb）
        List<Long> idList = getUserIdList(Long.valueOf(stepList.get(0).getStepMember()),deptId);
        if (idList.size() == 0) {
            throw new CustomException("审核用户未知，开启流程失败！");
        }
        flowBiz.setCurrentStepUser(StringUtils.join(idList, ","));
        flowBiz.setCurrentStepUserName(getUserNames(idList));
        flowBiz.setCurrentStatus(FlowBizStatusEnum.CHECK.getCode());
        flowBiz.setBizStatusCol(bizStatusCol);
        flowBiz.setBizBackStatus(bizBackStatus);
        flowBiz.setBizPassStatus(bizPassStatus);
        flowBiz.setBizRejectStatus(bizRejectStatus);
        flowBiz.setBizRevocationStatus(bizRevocationStatus);
        flowBiz.setFlowType("1");
        flowService.insertFlowBiz(flowBiz);
        return flowBiz;
    }

    /**
     *
     * 新增业务审核主流程 自定义
     *
     * @param flowDefinition 流程定义
     * @param stepList 流程定义步骤
     * @param bizId 业务数据id
     * @param bizTable 业务表名
     * @param bizStatusCol 业务表状态字段名
     * @param bizBackStatus 业务数据退回修改状态值
     * @param bizPassStatus 业务数据通过状态值
     * @return
     */
    private FlowBiz saveFlowBizCustomization(FlowDefinition flowDefinition,List<FlowBizStep> stepList,Long bizId, String bizTable,
                                String bizStatusCol,Integer bizBackStatus,Integer bizPassStatus,Integer bizRejectStatus,
                                Integer bizRevocationStatus){
        //存入业务流程表
        FlowBiz flowBiz = new FlowBiz();
        flowBiz.setFlowId(flowDefinition.getId());
        flowBiz.setBizId(bizId);
        flowBiz.setFlowName(flowDefinition.getFlowName());
        flowBiz.setFlowFlag(flowDefinition.getFlowFlag());
        flowBiz.setFlowVersion(flowDefinition.getVersion());
        flowBiz.setBizTable(bizTable);
        flowBiz.setCurrentStep(stepList.get(0).getStepNo());
        flowBiz.setTotalStep(stepList.size());
        flowBiz.setCurrentStepName(stepList.get(0).getStepName());
        flowBiz.setCurrentStepMember(stepList.get(0).getStepMember());
        //更新当前步骤用户
        flowBiz.setCurrentStepUser(stepList.get(0).getStepUser());
        flowBiz.setCurrentStepUserName(stepList.get(0).getStepUserName());
        flowBiz.setCurrentStatus(FlowBizStatusEnum.CHECK.getCode());
        flowBiz.setBizStatusCol(bizStatusCol);
        flowBiz.setBizBackStatus(bizBackStatus);
        flowBiz.setBizPassStatus(bizPassStatus);
        flowBiz.setBizRejectStatus(bizRejectStatus);
        flowBiz.setBizRevocationStatus(bizRevocationStatus);
        flowBiz.setFlowType("2");
        flowService.insertFlowBiz(flowBiz);
        return flowBiz;
    }


    /**
     *
     * 新增业务审核流程步骤
     *
     * @param deptId 部门id
     * @param stepList 流程步骤
     * @param flowBiz 主流程
     */
    private void saveBizFlowStep(Long deptId, List<FlowStep> stepList, FlowBiz flowBiz) {
        List<Long> stepUserIdList = new ArrayList<>();
        AtomicInteger stepNum = new AtomicInteger();
        stepList.forEach(item -> {
            FlowBizStep flowBizStep = new FlowBizStep();
            flowBizStep.setFlowBizId(flowBiz.getId());
            flowBizStep.setStepNo(item.getSort());
            flowBizStep.setStepMember(item.getStepMember());
            flowBizStep.setStepName(item.getStepName());
            // 添加当前用户ID及用户名称（String类型，可多用户，格式aaa，bbb）
            List<Long> userIdList = getUserIdList(Long.valueOf(item.getStepMember()), deptId);
            stepUserIdList.addAll(userIdList);
            flowBizStep.setStepUser(StringUtils.join(userIdList, ","));
            flowBizStep.setStepUserName(getUserNames(userIdList));
            stepNum.addAndGet(sqlManager.insertTemplate(flowBizStep));
        });
        if (stepList.size() != stepNum.get()) {
            throw new CustomException("开启流程异常！");
        }
        FlowBiz target = new FlowBiz();
        target.setId(flowBiz.getId());
        target.setFlowUser(StringUtils.join(stepUserIdList, ","));
        sqlManager.updateTemplateById(target);
    }

    /**
     *
     * 新增业务审核流程步骤
     *
     * @param deptId 部门id
     * @param stepList 流程步骤
     * @param flowBiz 主流程
     */
    private void saveBizFlowStepCustomization(Long deptId, List<FlowBizStep> stepList, FlowBiz flowBiz) {
        List<Long> stepUserIdList = new ArrayList<>();
        AtomicInteger stepNum = new AtomicInteger();
        for (int i=0;i<stepList.size();i++){
            stepList.get(i).setFlowBizId(flowBiz.getId());
            if (i == (stepList.size()-1)){
                // 添加当前用户ID及用户名称（String类型，可多用户，格式aaa，bbb）
                List<Long> userIdList = getUserIdList(Long.valueOf(stepList.get(i).getStepMember()), deptId);
                stepUserIdList.addAll(userIdList);
                stepList.get(i).setStepUser(StringUtils.join(userIdList, ","));
                stepList.get(i).setStepUserName(getUserNames(userIdList));
            }else {
                stepUserIdList.addAll(Arrays.stream(stepList.get(i).getStepUser().split(",")).map(Long::valueOf).collect(Collectors.toList()));
            }
            stepNum.addAndGet(sqlManager.insertTemplate(stepList.get(i)));
        }

//        stepList.forEach(item -> {
//            FlowBizStep flowBizStep = new FlowBizStep();
//            flowBizStep.setFlowBizId(flowBiz.getId());
//            flowBizStep.setStepNo(item.getStepNo());
//            flowBizStep.setStepMember(item.getStepMember());
//            flowBizStep.setStepName(item.getStepName());
//            if (item.get)
//            // 添加当前用户ID及用户名称（String类型，可多用户，格式aaa，bbb）
//            List<Long> userIdList = getUserIdList(Long.valueOf(item.getStepMember()), deptId);
//            stepUserIdList.addAll(userIdList);
//            flowBizStep.setStepUser(StringUtils.join(userIdList, ","));
//            flowBizStep.setStepUserName(getUserNames(userIdList));
//            stepNum.addAndGet(sqlManager.insertTemplate(flowBizStep));
//        });
        if (stepList.size() != stepNum.get()) {
            throw new CustomException("开启流程异常！");
        }
        FlowBiz target = new FlowBiz();
        target.setId(flowBiz.getId());
        target.setFlowUser(StringUtils.join(stepUserIdList, ","));
        sqlManager.updateTemplateById(target);
    }


    /**************************************************** 流程下一步相关方法 ****************************************************/

    /**
     * 提前终止流程
     *
     * @param currentFlowBiz  当前主流程
     * @param targetStepList  流程步骤
     * @param currentStep  当前流程步骤
     */
    private void earlyTerminateFlow(FlowBiz currentFlowBiz,List<FlowBizStep> targetStepList,FlowBizStep currentStep ,FlowBizModel flowBizModel){
        if (!BooleanUtils.toBoolean(flowBizModel.getIsEarlyTerminate())) {
            return;
        }
        if (!FlowBizStatusEnum.PASS.getCode().equals(flowBizModel.getStatus())){
            throw new CustomException("审核通过才可提前终止审核流程！");
        }
        //流程提前终止，则删除该流程后续未操作步骤
        List<FlowBizStep> deleteStepList = targetStepList.stream().filter(s -> s.getStepNo() > currentStep.getStepNo()).collect(Collectors.toList());
        deleteStepList.forEach(s ->{
            sqlManager.deleteById(FlowBizStep.class,s.getId());
        });
    }

    /**
     * @author cong.fang
     * @since  2022-09-13
     *
     * 流程步骤变更操作(删除及新增审核节点)
     *
     * @param stepList 流程步骤集合（升序排列）
     * @param currentStep 当前流程步骤
     * @param deleteId 需删除的流程步骤id
     * @param addUserIds 需添加流程步骤的用户id（可多个，逗号隔开，例aaa,bbb）
     * @param addStepName 添加的流程步骤名称
     * @return 流程是否有变更（true 已变更 false 未变更）
     */
    private boolean flowChange(List<FlowBizStep> stepList,FlowBizStep currentStep,Long deleteId,String addUserIds,String addStepName){
        boolean changeFlag = true;
        if (null != deleteId && StringUtils.isNotEmpty(addUserIds)) {
            //提取删除的流程步骤
            FlowBizStep deleteStep = stepList.stream().filter(s ->s.getId().equals(deleteId)).findAny().orElse(null);
            if (null != deleteStep) {
                //若删除审核节点同时添加新的审核节点，直接替换更新原节点
                FlowBizStep addStep = new FlowBizStep();
                addStep.setId(deleteStep.getId());
                addStep.setStepNo(deleteStep.getStepNo());
                addStep.setFlowBizId(deleteStep.getFlowBizId());
                addStep.setStepUser(addUserIds);
                addStep.setStepUserName(getUserNames(addUserIds));
                addStep.setStepName(addStepName);
                sqlManager.updateById(addStep);
            }
        } else if (null != deleteId && StringUtils.isEmpty(addUserIds)) {
            //提取删除的流程步骤
            FlowBizStep deleteStep = stepList.stream().filter(s ->s.getId().equals(deleteId)).findAny().orElse(null);
            if (null != deleteStep) {
                //若只删除审核节点，则所有后序节点步骤序号前移一位
                List<FlowBizStep> updateStepList = stepList.stream().filter(s -> s.getStepNo() > deleteStep.getStepNo()).collect(Collectors.toList());
                updateStepList.forEach(s -> s.setStepNo(s.getStepNo() -1));
                //删除需移除的审核节点
                sqlManager.deleteById(FlowBizStep.class,deleteId);
                //修改后序节点序号
                sqlManager.updateBatchTemplateById(FlowBizStep.class,updateStepList);
            }
        }else if (null == deleteId && StringUtils.isNotEmpty(addUserIds)){
            //若只添加审核节点，则所有后序节点步骤序号后移一位
            List<FlowBizStep> updateStepList = stepList.stream().filter(s -> s.getStepNo() > currentStep.getStepNo()).collect(Collectors.toList());
            FlowBizStep addStep = new FlowBizStep();
            addStep.setStepNo(currentStep.getStepNo() + 1);
            addStep.setFlowBizId(currentStep.getFlowBizId());
            addStep.setStepUser(addUserIds);
            addStep.setStepUserName(getUserNames(addUserIds));
            addStep.setStepName(addStepName);
            //新增添加的节点
            sqlManager.insertTemplate(addStep);
            //修改后序节点序号
            updateStepList.forEach(s -> s.setStepNo(s.getStepNo() + 1));
            sqlManager.updateBatchTemplateById(FlowBizStep.class,updateStepList);
        }else {
            changeFlag = false;
        }
        return changeFlag;
    }


    /**
     * @author cong.fang
     * @since  2022-09-13
     *
     * 退回修改，流程步骤相关操作
     *
     * @param currentFlowBiz 当前主流程
     * @param targetStepList 流程步骤
     * @param currentStep 当前流程步骤
     * @param deptId 部门id
     * @return 操作后流程步骤
     */
    private List<FlowBizStep> goBackFlowStep(FlowBiz currentFlowBiz,List<FlowBizStep> targetStepList,FlowBizStep currentStep, Long deptId, Long bizDataCreateBy){
        //流程退回修改，则删除该流程后续未操作步骤
        List<FlowBizStep> deleteStepList = targetStepList.stream().filter(s -> s.getStepNo() > currentStep.getStepNo()).collect(Collectors.toList());
        deleteStepList.forEach(s ->{
            sqlManager.deleteById(FlowBizStep.class,s.getId());
        });
        //原始步骤移除已删除步骤
        targetStepList.removeAll(deleteStepList);
        // 如果是标准流程，就走 接入流程定义
        // 如果是自定义流程，直接退回上一步
        FlowBiz target = new FlowBiz();
        target.setId(currentFlowBiz.getId());
        //修改当前操作人为业务数据的创建人
        target.setCurrentStepUser(bizDataCreateBy.toString());
        target.setCurrentStepUserName(TranslateUtil.getUserName(bizDataCreateBy));
        sqlManager.updateTemplateById(target);
        return targetStepList;
    }


    /**
     * @author cong.fang
     * @since  2022-09-13
     *
     * 最终步业务表操作
     *
     * @param currentFlowBiz 当前主流程
     * @param bizStatus 业务数据状态
     * @return 更新结果
     */
    private int finalFlowStep(FlowBiz currentFlowBiz ,Integer bizStatus){
        //同时更新业务表状态
        Map<String, Object> bizStatusInfo = new HashMap<>();
        bizStatusInfo.put("tableName", currentFlowBiz.getBizTable());
        bizStatusInfo.put("tableCol", currentFlowBiz.getBizStatusCol());
        bizStatusInfo.put("status", bizStatus);
        bizStatusInfo.put("bizId", currentFlowBiz.getBizId());
        return sqlManager.update("flowBiz.updateBizTableStatus", bizStatusInfo);
    }


    /**
     * @author cong.fang
     * @since  2022-09-13
     *
     * 最终结果操作，更新业务数据表，更新主流程
     *
     * @param currentFlowBiz 当前主流程
     * @param stepList 流程步骤
     * @param currentStep 当前流程步骤
     * @param flowBizModel 主流程
     * @return 更新结果
     */
    private int flowBizNext(FlowBiz currentFlowBiz, List<FlowBizStep> stepList,FlowBizStep currentStep, FlowBizModel flowBizModel, boolean updateStatusFlag){
        AdminUserVO adminUserVO = AdminUserContext.getUser();
        FlowBiz flowBiz = new FlowBiz();
        flowBiz.setId(currentFlowBiz.getId());
        //记录当前操作人为流程之前步骤用户（即可撤回用户）
        flowBiz.setBeforeStepUser(adminUserVO.getId());
        if (updateStatusFlag) {
            flowBiz.setCurrentStatus(flowBizModel.getStatus());
        }else {
            if (currentStep.getStepNo() < stepList.size() || !BooleanUtils.toBoolean(null == flowBizModel.getIsEarlyTerminate() ? 0 : flowBizModel.getIsEarlyTerminate())) {
                flowBiz.setCurrentStep(currentFlowBiz.getCurrentStep() + 1);
                flowBiz.setCurrentStepMember(stepList.get(currentStep.getStepNo()).getStepMember());
                flowBiz.setCurrentStepName(stepList.get(currentStep.getStepNo()).getStepName());
                flowBiz.setCurrentStepUser(stepList.get(currentStep.getStepNo()).getStepUser());
                flowBiz.setCurrentStepUserName(stepList.get(currentStep.getStepNo()).getStepUserName());
            }
        }
        return sqlManager.updateTemplateById(flowBiz);
    }


    /**
     * 更新当前步骤的审核相关信息
     * @param currentStep 当前流程步骤
     * @param flowBizModel 请求参数
     * @return
     */
    private int updateCurrentStep(FlowBizStep currentStep,FlowBizModel flowBizModel){
        //更新业务流程明细表数据
        //添加抄送用户
        if (StringUtils.isNotEmpty(flowBizModel.getCcUserIds())) {
            currentStep.setCcUser(flowBizModel.getCcUserIds());
            currentStep.setCcUserName(getUserNames(flowBizModel.getCcUserIds()));
        }
        currentStep.setStepStatus(flowBizModel.getStatus());
        currentStep.setStepComment(flowBizModel.getComment());
        currentStep.setESignature(flowBizModel.getESignature());
        AdminUserVO adminUserVO = AdminUserContext.getUser();
        currentStep.setStepUser(adminUserVO.getId().toString());
        currentStep.setStepUserName(adminUserVO.getName());
        currentStep.setUpdateTime(new Date());
        currentStep.setUpdateBy(adminUserVO.getId());
        return sqlManager.updateTemplateById(currentStep);
    }


    /**
     * @author cong.fang
     * @since  2022-09-13
     *
     * 更新主流程可见用户信息
     *
     * @param currentFlowBiz 当前主流程
     * @return 更新结果
     */
    private int updateFlowUser(FlowBiz currentFlowBiz){
        LambdaQuery<FlowBizStep> stepQuery = sqlManager.lambdaQuery(FlowBizStep.class);
        List<FlowBizStep> stepList = stepQuery.andEq(FlowBizStep::getFlowBizId, currentFlowBiz.getId())
                .orderBy("step_no asc").select();
        StringBuilder flowUser = new StringBuilder();
        stepList.forEach(s ->{
            if (StringUtils.isNotEmpty(flowUser)) {
                flowUser.append(",");
            }
            if (StringUtils.isNotEmpty(s.getStepUser())) {
                flowUser.append(s.getStepUser());
            }
            if (StringUtils.isNotEmpty(s.getCcUser())) {
                flowUser.append(",").append(s.getCcUser());
            }
        });

        FlowBiz flowBiz = new FlowBiz();
        flowBiz.setId(currentFlowBiz.getId());
        flowBiz.setFlowUser(flowUser.toString());
        return sqlManager.updateTemplateById(flowBiz);
    }


    /**
     * @author cong.fang
     * @since  2022-09-09
     *
     * 根据角色id和部门id查询用户
     *
     * @param roleId 角色id
     * @param deptId 部门id
     * @return 用户id集合
     */
    private List<Long> getUserIdList(Long roleId, Long deptId) {
        QueryUserByRoleIdDTO queryUserByRoleIdDTO = new QueryUserByRoleIdDTO();
        queryUserByRoleIdDTO.setRoleId(roleId);
        queryUserByRoleIdDTO.setToolCode(toolCode);
        queryUserByRoleIdDTO.setToolVersion(toolVersion);
        RtnInfo<List<AdminUserVO>> result = adminRemoteService.queryUserByRoleId(queryUserByRoleIdDTO);
        List<Long> userIdListForRole = result.getData().stream().map(AdminUserVO::getId).collect(Collectors.toList());
        List<Long> userIdListForRoleAndDept = result.getData().stream()
                .filter(u -> Objects.equals(deptId, u.getDeptid())).collect(Collectors.toList()).stream()
                .map(AdminUserVO::getId).collect(Collectors.toList());
        return userIdListForRoleAndDept.size() > 0 ? userIdListForRoleAndDept : userIdListForRole;
    }


    /**************************************************** 角色用户相关方法 ****************************************************/

    /**
     * @author cong.fang
     * @since  2022-09-09
     *
     * 根据角色id和部门id查询用户
     *
     * @param roleId 角色id
     * @param deptId 部门id
     * @return 用户ids（逗号分隔字符串,例aaa,bbb）
     */
    private String getUserIds(Long roleId, Long deptId) {
        List<Long> userIdList = getUserIdList(roleId,deptId);
        return StringUtils.join(userIdList, ",");
    }


    /**
     * @author cong.fang
     * @since  2022-09-09
     *
     * 用户id集合翻译用户名称
     *
     * @param userIdList
     * @return 用户名称（逗号分隔字符串）
     */
    private String getUserNames(List<Long> userIdList) {
        List<String> userNameList = new ArrayList<>();
        for (Long id :userIdList){
            userNameList.add(TranslateUtil.getUserName(id));
        }
        return StringUtils.join(userNameList, ",");
    }

    /**
     * @author cong.fang
     * @since  2022-09-09
     *
     * 用户ids翻译用户名称
     *
     * @param userIds
     * @return 用户名称（逗号分隔字符串）
     */
    private String getUserNames(String userIds) {
        List<Long> userIdList = Arrays.stream(userIds.split(",")).map(Long::valueOf).collect(Collectors.toList());
        List<String> userNameList = new ArrayList<>();
        for (Long id :userIdList){
            userNameList.add(TranslateUtil.getUserName(id));
        }
        return StringUtils.join(userNameList, ",");
    }

    @Override
    public List<FlowBizStep> getFlowStepListDesc(Long flowId){
        FlowBizStep step = new FlowBizStep();
        step.setFlowBizId(flowId);
        return sqlManager.select("flowBiz.selectStepListDesc",FlowBizStep.class,step);
    }

}
